home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / machine / z80fmly.c < prev    next >
C/C++ Source or Header  |  2000-04-23  |  20KB  |  753 lines

  1. /***************************************************************************
  2.  
  3.   Z80 FMLY.C   Z80 FAMILY CHIP EMURATOR for MAME Ver.0.1 alpha
  4.  
  5.   Support chip :  Z80PIO , Z80CTC
  6.  
  7.   Copyright(C) 1997 Tatsuyuki Satoh.
  8.  
  9.   This version are tested starforce driver.
  10.  
  11.   8/21/97 -- Heavily modified by Aaron Giles to be much more accurate for the MCR games
  12.   8/27/97 -- Rewritten a second time by Aaron Giles, with the datasheets in hand
  13.  
  14. pending:
  15.     Z80CTC , Counter mode & Timer with Trigrt start :not support Triger level
  16.  
  17. ***************************************************************************/
  18.  
  19. #include <stdio.h>
  20. #include "driver.h"
  21. #include "z80fmly.h"
  22. #include "cpu/z80/z80.h"
  23.  
  24. typedef struct
  25. {
  26.     int vector;                 /* interrupt vector */
  27.     int clock;                  /* system clock */
  28.     double invclock16;          /* 16/system clock */
  29.     double invclock256;         /* 256/system clock */
  30.     void (*intr)(int which);    /* interrupt callback */
  31.     mem_write_handler zc[4];    /* zero crossing callbacks */
  32.     int notimer;                /* no timer masks */
  33.     int mask[4];                /* masked channel flags */
  34.     int mode[4];                /* current mode */
  35.     int tconst[4];              /* time constant */
  36.     int down[4];                /* down counter (clock mode only) */
  37.     int extclk[4];              /* current signal from the external clock */
  38.     void *timer[4];             /* array of active timers */
  39.  
  40.     int int_state[4];           /* interrupt status (for daisy chain) */
  41. } z80ctc;
  42.  
  43. static z80ctc ctcs[MAX_CTC];
  44.  
  45.  
  46. /* these are the bits of the incoming commands to the CTC */
  47. #define INTERRUPT            0x80
  48. #define INTERRUPT_ON     0x80
  49. #define INTERRUPT_OFF    0x00
  50.  
  51. #define MODE                0x40
  52. #define MODE_TIMER        0x00
  53. #define MODE_COUNTER        0x40
  54.  
  55. #define PRESCALER            0x20
  56. #define PRESCALER_256    0x20
  57. #define PRESCALER_16        0x00
  58.  
  59. #define EDGE                0x10
  60. #define EDGE_FALLING        0x00
  61. #define EDGE_RISING        0x10
  62.  
  63. #define TRIGGER            0x08
  64. #define TRIGGER_AUTO        0x00
  65. #define TRIGGER_CLOCK    0x08
  66.  
  67. #define CONSTANT            0x04
  68. #define CONSTANT_LOAD    0x04
  69. #define CONSTANT_NONE    0x00
  70.  
  71. #define RESET                0x02
  72. #define RESET_CONTINUE    0x00
  73. #define RESET_ACTIVE        0x02
  74.  
  75. #define CONTROL            0x01
  76. #define CONTROL_VECTOR    0x00
  77. #define CONTROL_WORD        0x01
  78.  
  79. /* these extra bits help us keep things accurate */
  80. #define WAITING_FOR_TRIG    0x100
  81.  
  82.  
  83. static void z80ctc_timercallback (int param);
  84.  
  85.  
  86. void z80ctc_init (z80ctc_interface *intf)
  87. {
  88.     int i;
  89.  
  90.     memset (ctcs, 0, sizeof (ctcs));
  91.  
  92.     for (i = 0; i < intf->num; i++)
  93.     {
  94.         ctcs[i].clock = intf->baseclock[i];
  95.         ctcs[i].invclock16 = 16.0 / (double)intf->baseclock[i];
  96.         ctcs[i].invclock256 = 256.0 / (double)intf->baseclock[i];
  97.         ctcs[i].notimer = intf->notimer[i];
  98.         ctcs[i].intr = intf->intr[i];
  99.         ctcs[i].zc[0] = intf->zc0[i];
  100.         ctcs[i].zc[1] = intf->zc1[i];
  101.         ctcs[i].zc[2] = intf->zc2[i];
  102.         ctcs[i].zc[3] = 0;
  103.         z80ctc_reset (i);
  104.     }
  105. }
  106.  
  107.  
  108. double z80ctc_getperiod (int which, int ch)
  109. {
  110.     z80ctc *ctc = ctcs + which;
  111.     double clock;
  112.     int mode;
  113.  
  114.     /* keep channel within range, and get the current mode */
  115.     ch &= 3;
  116.     mode = ctc->mode[ch];
  117.  
  118.     /* if reset active */
  119.     if( (mode & RESET) == RESET_ACTIVE) return 0;
  120.     /* if counter mode */
  121.     if( (mode & MODE) == MODE_COUNTER)
  122.     {
  123.         logerror("CTC %d is CounterMode : Can't calcrate period\n", ch );
  124.         return 0;
  125.     }
  126.  
  127.     /* compute the period */
  128.     clock = ((mode & PRESCALER) == PRESCALER_16) ? ctc->invclock16 : ctc->invclock256;
  129.     return clock * (double)ctc->tconst[ch];
  130. }
  131.  
  132. /* interrupt request callback with daisy-chain circuit */
  133. static void z80ctc_interrupt_check( z80ctc *ctc )
  134. {
  135.     int state = 0;
  136.     int ch;
  137.  
  138.     for( ch = 3 ; ch >= 0 ; ch-- )
  139.     {
  140.         /* if IEO disable , same and lower IRQ is masking */
  141. /* ASG: changed this line because this state could have an interrupt pending as well! */
  142. /*        if( ctc->int_state[ch] & Z80_INT_IEO ) state  = Z80_INT_IEO;*/
  143.         if( ctc->int_state[ch] & Z80_INT_IEO ) state  = ctc->int_state[ch];
  144.         else                                   state |= ctc->int_state[ch];
  145.     }
  146.     /* change interrupt status */
  147.     if (ctc->intr) (*ctc->intr)(state);
  148. }
  149.  
  150.  
  151. void z80ctc_reset (int which)
  152. {
  153.     z80ctc *ctc = ctcs + which;
  154.     int i;
  155.  
  156.     /* set up defaults */
  157.     for (i = 0; i < 4; i++)
  158.     {
  159.         ctc->mode[i] = RESET_ACTIVE;
  160.         ctc->tconst[i] = 0x100;
  161.         if (ctc->timer[i])
  162.             timer_remove (ctc->timer[i]);
  163.         ctc->timer[i] = NULL;
  164.         ctc->int_state[i] = 0;
  165.     }
  166.     z80ctc_interrupt_check( ctc );
  167. }
  168.  
  169. void z80ctc_0_reset (void) { z80ctc_reset (0); }
  170. void z80ctc_1_reset (void) { z80ctc_reset (1); }
  171.  
  172.  
  173. void z80ctc_w (int which, int offset, int data)
  174. {
  175.     z80ctc *ctc = ctcs + which;
  176.     int mode, ch;
  177.  
  178.     /* keep channel within range, and get the current mode */
  179.     ch = offset & 3;
  180.     mode = ctc->mode[ch];
  181.  
  182.     /* if we're waiting for a time constant, this is it */
  183.     if ((mode & CONSTANT) == CONSTANT_LOAD)
  184.     {
  185.         /* set the time constant (0 -> 0x100) */
  186.         ctc->tconst[ch] = data ? data : 0x100;
  187.  
  188.         /* clear the internal mode -- we're no longer waiting */
  189.         ctc->mode[ch] &= ~CONSTANT;
  190.  
  191.         /* also clear the reset, since the constant gets it going again */
  192.         ctc->mode[ch] &= ~RESET;
  193.  
  194.         /* if we're in timer mode.... */
  195.         if ((mode & MODE) == MODE_TIMER)
  196.         {
  197.             /* if we're triggering on the time constant, reset the down counter now */
  198.             if ((mode & TRIGGER) == TRIGGER_AUTO)
  199.             {
  200.                 double clock = ((mode & PRESCALER) == PRESCALER_16) ? ctc->invclock16 : ctc->invclock256;
  201.                 if (ctc->timer[ch])
  202.                     timer_remove (ctc->timer[ch]);
  203.                 if (!(ctc->notimer & (1<<ch)))
  204.                     ctc->timer[ch] = timer_pulse (clock * (double)ctc->tconst[ch], (which << 2) + ch, z80ctc_timercallback);
  205.             }
  206.  
  207.             /* else set the bit indicating that we're waiting for the appropriate trigger */
  208.             else
  209.                 ctc->mode[ch] |= WAITING_FOR_TRIG;
  210.         }
  211.  
  212.         /* also set the down counter in case we're clocking externally */
  213.         ctc->down[ch] = ctc->tconst[ch];
  214.  
  215.         /* all done here */
  216.         return;
  217.     }
  218.  
  219.     /* if we're writing the interrupt vector, handle it specially */
  220. #if 0    /* Tatsuyuki Satoh changes */
  221.     /* The 'Z80family handbook' wrote,                            */
  222.     /* interrupt vector is able to set for even channel (0 or 2)  */
  223.     if ((data & CONTROL) == CONTROL_VECTOR && (ch&1) == 0)
  224. #else
  225.     if ((data & CONTROL) == CONTROL_VECTOR && ch == 0)
  226. #endif
  227.     {
  228.         ctc->vector = data & 0xf8;
  229.         logerror("CTC Vector = %02x\n", ctc->vector);
  230.         return;
  231.     }
  232.  
  233.     /* this must be a control word */
  234.     if ((data & CONTROL) == CONTROL_WORD)
  235.     {
  236.         /* set the new mode */
  237.         ctc->mode[ch] = data;
  238.         logerror("CTC ch.%d mode = %02x\n", ch, data);
  239.  
  240.         /* if we're being reset, clear out any pending timers for this channel */
  241.         if ((data & RESET) == RESET_ACTIVE)
  242.         {
  243.             if (ctc->timer[ch])
  244.                 timer_remove (ctc->timer[ch]);
  245.             ctc->timer[ch] = NULL;
  246.  
  247.             if( ctc->int_state[ch] != 0 )
  248.             {
  249.                 /* clear interrupt service , request */
  250.                 ctc->int_state[ch] = 0;
  251.                 z80ctc_interrupt_check( ctc );
  252.             }
  253.         }
  254.  
  255.         /* all done here */
  256.         return;
  257.     }
  258. }
  259.  
  260. WRITE_HANDLER( z80ctc_0_w ) { z80ctc_w (0, offset, data); }
  261. WRITE_HANDLER( z80ctc_1_w ) { z80ctc_w (1, offset, data); }
  262.  
  263.  
  264. int z80ctc_r (int which, int ch)
  265. {
  266.     z80ctc *ctc = ctcs + which;
  267.     int mode;
  268.  
  269.     /* keep channel within range */
  270.     ch &= 3;
  271.     mode = ctc->mode[ch];
  272.  
  273.     /* if we're in counter mode, just return the count */
  274.     if ((mode & MODE) == MODE_COUNTER)
  275.         return ctc->down[ch];
  276.  
  277.     /* else compute the down counter value */
  278.     else
  279.     {
  280.         double clock = ((mode & PRESCALER) == PRESCALER_16) ? ctc->invclock16 : ctc->invclock256;
  281.  
  282. logerror("CTC clock %f\n",1.0/clock);
  283.  
  284.  
  285.         if (ctc->timer[ch])
  286.             return ((int)(timer_timeleft (ctc->timer[ch]) / clock) + 1) & 0xff;
  287.         else
  288.             return 0;
  289.     }
  290. }
  291.  
  292. READ_HANDLER( z80ctc_0_r ) { return z80ctc_r (0, offset); }
  293. READ_HANDLER( z80ctc_1_r ) { return z80ctc_r (1, offset); }
  294.  
  295.  
  296. int z80ctc_interrupt( int which )
  297. {
  298.     z80ctc *ctc = ctcs + which;
  299.     int ch;
  300.  
  301.     for( ch = 0 ; ch < 4 ; ch++ )
  302.     {
  303.         if( ctc->int_state[ch] )
  304.         {
  305.             if( ctc->int_state[ch] == Z80_INT_REQ)
  306.                 ctc->int_state[ch] = Z80_INT_IEO;
  307.             break;
  308.         }
  309.     }
  310.     if( ch > 3 )
  311.     {
  312.         logerror("CTC entry INT : non IRQ\n");
  313.         ch = 0;
  314.     }
  315.     z80ctc_interrupt_check( ctc );
  316.     return ctc->vector + ch * 2;
  317. }
  318.  
  319. /* when operate RETI , soud be call this function for request pending interrupt */
  320. void z80ctc_reti( int which )
  321. {
  322.     z80ctc *ctc = ctcs + which;
  323.     int ch;
  324.  
  325.     for( ch = 0 ; ch < 4 ; ch++ )
  326.     {
  327.         if( ctc->int_state[ch] & Z80_INT_IEO )
  328.         {
  329.             /* highest served interrupt found */
  330.             /* clear interrupt status */
  331.             ctc->int_state[ch] &= ~Z80_INT_IEO;
  332.             /* search next interrupt */
  333.             break;
  334.         }
  335.     }
  336.     /* set next interrupt stattus */
  337.     z80ctc_interrupt_check( ctc );
  338. }
  339.  
  340. static void z80ctc_timercallback (int param)
  341. {
  342.     int which = param >> 2;
  343.     int ch = param & 3;
  344.     z80ctc *ctc = ctcs + which;
  345.  
  346.     /* down counter has reached zero - see if we should interrupt */
  347.     if ((ctc->mode[ch] & INTERRUPT) == INTERRUPT_ON)
  348.     {
  349.         if( !(ctc->int_state[ch] & Z80_INT_REQ) )
  350.         {
  351.             ctc->int_state[ch] |= Z80_INT_REQ;
  352.             z80ctc_interrupt_check( ctc );
  353.         }
  354.     }
  355.     /* generate the clock pulse */
  356.     if (ctc->zc[ch])
  357.     {
  358.         (*ctc->zc[ch])(0,1);
  359.         (*ctc->zc[ch])(0,0);
  360.     }
  361.  
  362.     /* reset the down counter */
  363.     ctc->down[ch] = ctc->tconst[ch];
  364. }
  365.  
  366.  
  367. void z80ctc_trg_w (int which, int trg, int offset, int data)
  368. {
  369.     z80ctc *ctc = ctcs + which;
  370.     int ch = trg & 3;
  371.     int mode;
  372.  
  373.     data = data ? 1 : 0;
  374.     mode = ctc->mode[ch];
  375.  
  376.     /* see if the trigger value has changed */
  377.     if (data != ctc->extclk[ch])
  378.     {
  379.         ctc->extclk[ch] = data;
  380.  
  381.         /* see if this is the active edge of the trigger */
  382.         if (((mode & EDGE) == EDGE_RISING && data) || ((mode & EDGE) == EDGE_FALLING && !data))
  383.         {
  384.             /* if we're waiting for a trigger, start the timer */
  385.             if ((mode & WAITING_FOR_TRIG) && (mode & MODE) == MODE_TIMER)
  386.             {
  387.                 double clock = ((mode & PRESCALER) == PRESCALER_16) ? ctc->invclock16 : ctc->invclock256;
  388.  
  389. logerror("CTC clock %f\n",1.0/clock);
  390.  
  391.  
  392.                 if (ctc->timer[ch])
  393.                     timer_remove (ctc->timer[ch]);
  394.                 if (!(ctc->notimer & (1<<ch)))
  395.                     ctc->timer[ch] = timer_pulse (clock * (double)ctc->tconst[ch], (which << 2) + ch, z80ctc_timercallback);
  396.             }
  397.  
  398.             /* we're no longer waiting */
  399.             ctc->mode[ch] &= ~WAITING_FOR_TRIG;
  400.  
  401.             /* if we're clocking externally, decrement the count */
  402.             if ((mode & MODE) == MODE_COUNTER)
  403.             {
  404.                 ctc->down[ch]--;
  405.  
  406.                 /* if we hit zero, do the same thing as for a timer interrupt */
  407.                 if (!ctc->down[ch])
  408.                     z80ctc_timercallback ((which << 2) + ch);
  409.             }
  410.         }
  411.     }
  412. }
  413.  
  414. WRITE_HANDLER( z80ctc_0_trg0_w ) { z80ctc_trg_w (0, 0, offset, data); }
  415. WRITE_HANDLER( z80ctc_0_trg1_w ) { z80ctc_trg_w (0, 1, offset, data); }
  416. WRITE_HANDLER( z80ctc_0_trg2_w ) { z80ctc_trg_w (0, 2, offset, data); }
  417. WRITE_HANDLER( z80ctc_0_trg3_w ) { z80ctc_trg_w (0, 3, offset, data); }
  418. WRITE_HANDLER( z80ctc_1_trg0_w ) { z80ctc_trg_w (1, 0, offset, data); }
  419. WRITE_HANDLER( z80ctc_1_trg1_w ) { z80ctc_trg_w (1, 1, offset, data); }
  420. WRITE_HANDLER( z80ctc_1_trg2_w ) { z80ctc_trg_w (1, 2, offset, data); }
  421. WRITE_HANDLER( z80ctc_1_trg3_w ) { z80ctc_trg_w (1, 3, offset, data); }
  422.  
  423.  
  424. /*---------------------- Z80 PIO ---------------------------------*/
  425.  
  426. /* starforce emurate Z80PIO subset */
  427. /* ch.A mode 1 input handshake mode from sound command */
  428. /* ch.b not use */
  429.  
  430.  
  431. #define PIO_MODE0 0x00        /* output mode */
  432. #define PIO_MODE1 0x01        /* input  mode */
  433. #define PIO_MODE2 0x02        /* i/o    mode */
  434. #define PIO_MODE3 0x03        /* bit    mode */
  435. /* pio controll port operation (bit 0-3) */
  436. #define PIO_OP_MODE 0x0f    /* mode select        */
  437. #define PIO_OP_INTC 0x07    /* interrupt controll */
  438. #define PIO_OP_INTE 0x03    /* interrupt enable   */
  439. #define PIO_OP_INTE 0x03    /* interrupt enable   */
  440. /* pio interrupt controll nit */
  441. #define PIO_INT_ENABLE 0x80  /* ENABLE : 0=disable , 1=enable */
  442. #define PIO_INT_AND    0x40  /* LOGIC  : 0=OR      , 1=AND    */
  443. #define PIO_INT_HIGH   0x20  /* LEVEL  : 0=low     , 1=high   */
  444. #define PIO_INT_MASK   0x10  /* MASK   : 0=off     , 1=on     */
  445.  
  446. typedef struct
  447. {
  448.     int vector[2];                        /* interrupt vector               */
  449.     void (*intr)(int which);              /* interrupt callbacks            */
  450.     void (*rdyr[2])(int data);            /* RDY active callback            */
  451.     int mode[2];                          /* mode 00=in,01=out,02=i/o,03=bit*/
  452.     int enable[2];                        /* interrupt enable               */
  453.     int mask[2];                          /* mask folowers                  */
  454.     int dir[2];                           /* direction (bit mode)           */
  455.     int rdy[2];                           /* ready pin level                */
  456.     int in[2];                            /* input port data                */
  457.     int out[2];                           /* output port                    */
  458.     int int_state[2];                     /* interrupt status (daisy chain) */
  459. } z80pio;
  460.  
  461. static z80pio pios[MAX_PIO];
  462.  
  463. /* initialize pio emurator */
  464. void z80pio_init (z80pio_interface *intf)
  465. {
  466.     int i;
  467.  
  468.     memset (pios, 0, sizeof (pios));
  469.  
  470.     for (i = 0; i < intf->num; i++)
  471.     {
  472.         pios[i].intr = intf->intr[i];
  473.         pios[i].rdyr[0] = intf->rdyA[i];
  474.         pios[i].rdyr[1] = intf->rdyB[i];
  475.         z80pio_reset (i);
  476.     }
  477. }
  478.  
  479. static void z80pio_interrupt_check( z80pio *pio )
  480. {
  481.     int state;
  482.  
  483.     if( pio->int_state[1] & Z80_INT_IEO ) state  = Z80_INT_IEO;
  484.     else                                  state  = pio->int_state[1];
  485.     if( pio->int_state[0] & Z80_INT_IEO ) state  = Z80_INT_IEO;
  486.     else                                  state |= pio->int_state[0];
  487.     /* change daisy chain status */
  488.     if (pio->intr) (*pio->intr)(state);
  489. }
  490.  
  491. static void z80pio_check_irq( z80pio *pio , int ch )
  492. {
  493.     int irq = 0;
  494.     int data;
  495.     int old_state;
  496.  
  497.     if( pio->enable[ch] & PIO_INT_ENABLE )
  498.     {
  499.         if( pio->mode[ch] == PIO_MODE3 )
  500.         {
  501.             data  =  pio->in[ch] & pio->dir[ch]; /* input data only */
  502.             data &= ~pio->mask[ch];              /* mask follow     */
  503.             if( !(pio->enable[ch]&PIO_INT_HIGH) )/* active level    */
  504.                 data ^= pio->mask[ch];             /* active low  */
  505.             if( pio->enable[ch]&PIO_INT_AND )    /* logic      */
  506.                  { if( data == pio->mask[ch] ) irq = 1; }
  507.             else { if( data == 0             ) irq = 1; }
  508.             /* if portB , portA mode 2 check */
  509.             if( ch && (pio->mode[0]==PIO_MODE2) )
  510.             {
  511.                 if( pio->rdy[ch] == 0 ) irq = 1;
  512.             }
  513.         }
  514.         else if( pio->rdy[ch] == 0 ) irq = 1;
  515.     }
  516.     old_state = pio->int_state[ch];
  517.     if( irq ) pio->int_state[ch] |=  Z80_INT_REQ;
  518.     else      pio->int_state[ch] &= ~Z80_INT_REQ;
  519.  
  520.     if( old_state != pio->int_state[ch] )
  521.         z80pio_interrupt_check( pio );
  522. }
  523.  
  524. void z80pio_reset (int which)
  525. {
  526.     z80pio *pio = pios + which;
  527.     int i;
  528.  
  529.     for( i = 0 ; i <= 1 ; i++){
  530.         pio->mask[i]   = 0xff;    /* mask all on */
  531.         pio->enable[i] = 0x00;    /* disable     */
  532.         pio->mode[i]   = 0x01;    /* mode input  */
  533.         pio->dir[i]    = 0x01;    /* dir  input  */
  534.         pio->rdy[i]    = 0x00;    /* RDY = low   */
  535.         pio->out[i]    = 0x00;    /* outdata = 0 */
  536.         pio->int_state[i] = 0;
  537.     }
  538.     z80pio_interrupt_check( pio );
  539. }
  540.  
  541. /* pio data register write */
  542. void z80pio_d_w( int which , int ch , int data )
  543. {
  544.     z80pio *pio = pios + which;
  545.     if( ch ) ch = 1;
  546.  
  547.     pio->out[ch] = data;    /* latch out data */
  548.     switch( pio->mode[ch] ){
  549.     case PIO_MODE0:            /* mode 0 output */
  550.     case PIO_MODE2:            /* mode 2 i/o */
  551.         pio->rdy[ch] = 1;    /* ready = H */
  552.         z80pio_check_irq( pio , ch );
  553.         return;
  554.     case PIO_MODE1:            /* mode 1 intput */
  555.     case PIO_MODE3:            /* mode 0 bit */
  556.         return;
  557.     default:
  558.         logerror("PIO-%c data write,bad mode\n",'A'+ch );
  559.     }
  560. }
  561.  
  562. /* pio controll register write */
  563. void z80pio_c_w( int which , int ch , int data )
  564. {
  565.     z80pio *pio = pios + which;
  566.     if( ch ) ch = 1;
  567.  
  568.     /* load direction phase ? */
  569.     if( pio->mode[ch] == 0x13 ){
  570.         pio->dir[ch] = data;
  571.         pio->mode[ch] = 0x03;
  572.         return;
  573.     }
  574.     /* load mask folows phase ? */
  575.     if( pio->enable[ch] & PIO_INT_MASK ){    /* load mask folows */
  576.         pio->mask[ch] = data;
  577.         pio->enable[ch] &= ~PIO_INT_MASK;
  578.         logerror("PIO-%c interrupt mask %02x\n",'A'+ch,data );
  579.         return;
  580.     }
  581.     switch( data & 0x0f ){
  582.     case PIO_OP_MODE:    /* mode select 0=out,1=in,2=i/o,3=bit */
  583.         pio->mode[ch] = (data >> 6 );
  584.         if( pio->mode[ch] == 0x03 ) pio->mode[ch] = 0x13;
  585.         logerror("PIO-%c Mode %x\n",'A'+ch,pio->mode[ch] );
  586.         break;
  587.     case PIO_OP_INTC:        /* interrupt control */
  588.         pio->enable[ch] = data & 0xf0;
  589.         pio->mask[ch]   = 0x00;
  590.         /* when interrupt enable , set vector request flag */
  591.         logerror("PIO-%c Controll %02x\n",'A'+ch,data );
  592.         break;
  593.     case PIO_OP_INTE:        /* interrupt enable controll */
  594.         pio->enable[ch] &= ~PIO_INT_ENABLE;
  595.         pio->enable[ch] |= (data & PIO_INT_ENABLE);
  596.         logerror("PIO-%c enable %02x\n",'A'+ch,data&0x80 );
  597.         break;
  598.     default:
  599.             if( !(data&1) )
  600.             {
  601.                 pio->vector[ch] = data;
  602.                 logerror("PIO-%c vector %02x\n",'A'+ch,data);
  603.             }
  604.             else logerror("PIO-%c illegal command %02x\n",'A'+ch,data );
  605.     }
  606.     /* interrupt check */
  607.     z80pio_check_irq( pio , ch );
  608. }
  609.  
  610. /* pio controll register read */
  611. int z80pio_c_r( int which , int ch )
  612. {
  613.     if( ch ) ch = 1;
  614.  
  615.     logerror("PIO-%c controll read\n",'A'+ch );
  616.     return 0;
  617. }
  618.  
  619. /* pio data register read */
  620. int z80pio_d_r( int which , int ch )
  621. {
  622.     z80pio *pio = pios + which;
  623.     if( ch ) ch = 1;
  624.  
  625.     switch( pio->mode[ch] ){
  626.     case PIO_MODE0:            /* mode 0 output */
  627.         return pio->out[ch];
  628.     case PIO_MODE1:            /* mode 1 intput */
  629.         pio->rdy[ch] = 1;    /* ready = H */
  630.         z80pio_check_irq( pio , ch );
  631.         return pio->in[ch];
  632.     case PIO_MODE2:            /* mode 2 i/o */
  633.         if( ch ) logerror("PIO-B mode 2 \n");
  634.         pio->rdy[1] = 1;    /* brdy = H */
  635.         z80pio_check_irq( pio , ch );
  636.         return pio->in[ch];
  637.     case PIO_MODE3:            /* mode 3 bit */
  638.         return (pio->in[ch]&pio->dir[ch])|(pio->out[ch]&~pio->dir[ch]);
  639.     }
  640.     logerror("PIO-%c data read,bad mode\n",'A'+ch );
  641.     return 0;
  642. }
  643.  
  644. int z80pio_interrupt( int which )
  645. {
  646.     z80pio *pio = pios + which;
  647.     int ch = 0;
  648.  
  649.     /* port A */
  650.     if( pio->int_state[0] == Z80_INT_REQ )
  651.     {
  652.         pio->int_state[0] |= Z80_INT_IEO;
  653.     } if( pio->int_state[0] == 0 )
  654.     {
  655.         /* port B */
  656.         ch = 1;
  657.         if( pio->int_state[1] == Z80_INT_REQ )
  658.         {
  659.             pio->int_state[1] |= Z80_INT_IEO;
  660.         }
  661.         else
  662.         {
  663.             logerror("PIO entry INT : non IRQ\n");
  664.             ch = 0;
  665.         }
  666.     }
  667.     z80pio_interrupt_check( pio );
  668.     return pio->vector[ch];
  669. }
  670.  
  671. void z80pio_reti( int which )
  672. {
  673.     z80pio *pio = pios + which;
  674.  
  675.     if( pio->int_state[0] & Z80_INT_IEO )
  676.     {
  677.         pio->int_state[0] &= ~Z80_INT_IEO;
  678.     } else if( pio->int_state[1] & Z80_INT_IEO )
  679.     {
  680.         pio->int_state[1] &= ~Z80_INT_IEO;
  681.     }
  682.     /* set next interrupt stattus */
  683.     z80pio_interrupt_check( pio );
  684. }
  685.  
  686. /* z80pio port write */
  687. void z80pio_p_w( int which , int ch , int data )
  688. {
  689.     z80pio *pio = pios + which;
  690.  
  691.     if( ch ) ch = 1;
  692.  
  693.     pio->in[ch]  = data;
  694.     switch( pio->mode[ch] ){
  695.     case PIO_MODE0:
  696.         logerror("PIO-%c OUTPUT mode and data write\n",'A'+ch );
  697.         break;
  698.     case PIO_MODE2:    /* only port A */
  699.         ch = 1;        /* handshake and IRQ is use portB */
  700.     case PIO_MODE1:
  701.         pio->rdy[ch] = 0;
  702.         z80pio_check_irq( pio , ch );
  703.         break;
  704.     case PIO_MODE3:
  705.         /* irq check */
  706.         z80pio_check_irq( pio , ch );
  707.         break;
  708.     }
  709. }
  710.  
  711. /* z80pio port read */
  712. int z80pio_p_r( int which , int ch )
  713. {
  714.     z80pio *pio = pios + which;
  715.  
  716.     if( ch ) ch = 1;
  717.  
  718.     switch( pio->mode[ch] ){
  719.     case PIO_MODE2:        /* port A only */
  720.     case PIO_MODE0:
  721.         pio->rdy[ch] = 0;
  722.         z80pio_check_irq( pio , ch );
  723.         break;
  724.     case PIO_MODE1:
  725.         logerror("PIO-%c INPUT mode and data read\n",'A'+ch );
  726.         break;
  727.     case PIO_MODE3:
  728.         /*     input bits                , output bits                */
  729.         return (pio->in[ch]&pio->dir[ch])|(pio->out[ch]&~pio->dir[ch]);
  730.     }
  731.     return pio->out[ch];
  732. }
  733.  
  734. /* for mame interface */
  735.  
  736. void z80pio_0_reset (void) { z80pio_reset (0); }
  737.  
  738. WRITE_HANDLER( z80pio_0_w )
  739. {
  740.     if(offset&1) z80pio_c_w(0,(offset/2)&1,data);
  741.     else         z80pio_d_w(0,(offset/2)&1,data);
  742. }
  743.  
  744. READ_HANDLER( z80pio_0_r )
  745. {
  746.     return (offset&1) ? z80pio_c_r(0,(offset/2)&1) : z80pio_d_r(0,(offset/2)&1);
  747. }
  748.  
  749. WRITE_HANDLER( z80pioA_0_p_w ) { z80pio_p_w(0,0,data);   }
  750. WRITE_HANDLER( z80pioB_0_p_w ) { z80pio_p_w(0,1,data);   }
  751. READ_HANDLER( z80pioA_0_p_r )           { return z80pio_p_r(0,0); }
  752. READ_HANDLER( z80pioB_0_p_r )           { return z80pio_p_r(0,1); }
  753.